package com.yk.dataGatherer.mapper;

import com.yk.api.dataGatherer.dto.DescribeDTO;
import com.yk.api.dataGatherer.dto.SelectDTO;
import com.yk.api.dataGatherer.dto.TableDTO;
import com.yk.api.dataGatherer.dto.TagsSelectDTO;
import com.yk.api.dataGatherer.vo.FieldsVo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * TdEngineMapper
 *
 * @author lmx
 * @date 2023/10/27 15:37
 */
@Mapper
public interface TdEngineMapper {

    /**
     * 创建数据库方法
     *
     * @param dataBaseName 数据库名称
     */
    void createDatabase(@Param("dataBaseName") String dataBaseName);

    /**
     * 创建超级表
     *
     * @param schemaFields   字段集合
     * @param tagsFields     tag字段集合
     * @param dataBaseName   数据库名称
     * @param superTableName 超级表名称
     */
    void createSuperTable(@Param("schemaFields") List<FieldsVo> schemaFields, @Param("tagsFields") List<FieldsVo> tagsFields, @Param("dataBaseName") String dataBaseName, @Param("superTableName") String superTableName);

    /**
     * 创建超级表的子表
     *
     * @param tableDto 入参的实体类
     */
    void createTable(TableDTO tableDto);

    /**
     * 删除超级表的子表
     *
     * @param tableDto 入参的实体类
     */
    void delTable(TableDTO tableDto);

    /**
     * 插入数据
     *
     * @param tableDto 入参的实体类
     */
    void insertData(TableDTO tableDto);

    /**
     * 根据时间戳查询数据
     *
     * @param selectDto 入参的实体类
     * @return 历史数据集合
     */
    List<Map<String, Object>> selectByTimestamp(SelectDTO selectDto);

    /**
     * 根据变量和时间戳查询历史数据
     *
     * @param selectDto 入参的实体类
     * @return 历史数据集合
     */
    List<Map<String, Object>> selectByVariableAndTime(SelectDTO selectDto);

    /**
     * 根据变量和时间戳查询历史数据 (分页)
     *
     * @param selectDto 入参的实体类
     * @param limit     分页条数
     * @param offset    分页偏移量
     * @return 历史数据集合
     */
    List<Map<String, Object>> pageByVariableAndTime(@Param("query") SelectDTO selectDto,
                                                    @Param("limit") Long limit, @Param("offset") Long offset);

    /**
     * 增加超级表字段
     *
     * @param superTableName 超级表名称
     * @param fieldsVo       字段对象
     */
    void addColumnForSuperTable(@Param("superTableName") String superTableName, @Param("fieldsVo") FieldsVo fieldsVo);

    /**
     * 删除超级表字段
     *
     * @param superTableName 超级表名称
     * @param fieldsVo       字段对象
     */
    void dropColumnForSuperTable(@Param("superTableName") String superTableName, @Param("fieldsVo") FieldsVo fieldsVo);

    /**
     * 增加超级表的Tags
     *
     * @param superTableName 超级表名称
     * @param fieldsVo       字段对象
     */
    void addTagForSuperTable(@Param("superTableName") String superTableName, @Param("fieldsVo") FieldsVo fieldsVo);

    /**
     * 删除超级表的Tags
     *
     * @param superTableName 超级表名称
     * @param fieldsVo       字段对象
     */
    void dropTagForSuperTable(@Param("superTableName") String superTableName, @Param("fieldsVo") FieldsVo fieldsVo);

    /**
     * 检查表是否存在
     *
     * @param dataBaseName 数据库名称
     * @param tableName    可以为超级表名或普通表名
     * @return
     */
    Map<String, Long> checkTableExists(@Param("dataBaseName") String dataBaseName, @Param("tableName") String tableName);

    /**
     * 根据时间统计
     *
     * @param selectDto 入参的实体类
     * @return 历史数据
     */
    Map<String, Long> getCountByTimestamp(SelectDTO selectDto);

    /**
     * 最新一条历史数据
     *
     * @param selectDto 入参的实体类
     * @return 历史数据
     */
    Map<String, Object> getLastData(SelectDTO selectDto);

    /**
     * 根据超级表查询包含Tags的最新数据集合
     *
     * @param tagsSelectDTO 入参的实体类
     * @return 历史数据集合
     */
    List<Map<String, Object>> getLastDataByTags(TagsSelectDTO tagsSelectDTO);

    /**
     * 根据Tags-(deviceId)查询动态数据列
     *
     * @param tagsSelectDTO 入参的实体类
     * @return 历史数据集合
     */
    List<Map<String, Object>> getDynamicDataByDeviceId(TagsSelectDTO tagsSelectDTO);

    /**
     * 获取超级表的结构信息
     *
     * @param dataBaseName   数据库名称
     * @param superTableName 超级表名称
     * @return
     */
    List<DescribeDTO> getColumn(@Param("dataBaseName") String dataBaseName, @Param("superTableName") String superTableName);

    /**
     * 根据时间删除数据
     *
     * @param selectDto 入参的实体类
     */
    void delDataByTime(SelectDTO selectDto);

    /**
     * 获取创建子表的sql语句
     *
     * @param dataBaseName 库名
     * @param tableName    设备id
     * @return
     */
    Map<String, String> getCreateTableSql(@Param("dataBaseName") String dataBaseName, @Param("tableName") String tableName);

    /**
     * 创建子表副本
     *
     * @param sql sql语句
     */
    void createTableCopy(@Param("sql") String sql);

    /**
     * 迁移设备数据
     */
    void deviceMigrate(@Param("dataBaseName") String dataBaseName, @Param("tableName") String tableName,
                       @Param("copyTableName") String copyTableName);

    /**
     * 删除子表
     */
    void delTableByName(@Param("dataBaseName") String dataBaseName, @Param("tableName") String tableName);

    /**
     * 根据时间范围查询历史数据最早一条
     *
     * @param address      列名
     * @param dataBaseName 库名
     * @param tableName    表名
     * @param startTime    开始时间
     * @param endTime      结束时间
     * @return 数据值
     */
    String selectLatestDataByTime(@Param("address") String address, @Param("dataBaseName") String dataBaseName,
                                  @Param("tableName") String tableName, @Param("startTime") Date startTime,
                                  @Param("endTime") Date endTime);
}
